<script setup lang="ts">
  import { ref, useTemplateRef, reactive, computed } from 'vue'
  import { QUploader, useQuasar, uid } from 'quasar'

  import CudTable, { type TQTableColumns, type TRequestParam } from '@/components/CudTable.vue'
  import {
    getHousePageList,
    addHouse,
    editHouse,
    removeHouse,
    type THouseQueryParams,
    type IHouseParam
  } from '@/api'
  import { getUserInfo, isRequestSuccess } from '@/utils'

  const $q = useQuasar()

  // 查旬功能
  const tableRef = useTemplateRef('houseTable')
  const statusOptions = ['全部状态', '未租', '已租']
  const layoutOptions = ['全部户型', '单身公寓', '1室1厅', '2室1厅', '2室2厅', '3室1厅', '3室2厅']
  const statusRef = ref('全部状态')
  const layoutRef = ref('全部户型')
  const filterRef = ref(null)
  const rUid = ref(uid())
  const classes = 'max-w-[160px] break-all'
  const columns: TQTableColumns = [
    { name: 'houseId', label: '房源ID', field: 'houseId', align: 'left', classes },
    { name: 'houseName', label: '房源名称', field: 'houseName', align: 'left', classes },
    { name: 'houseType', label: '房源类型', field: 'houseType', align: 'left', classes },
    {
      name: 'status',
      label: '状态',
      field: 'status',
      align: 'left',
      classes
    },
    { name: 'houseNumber', label: '房号', field: 'houseNumber', align: 'left', classes },
    { name: 'layout', label: '户型', field: 'layout', align: 'left', classes },
    { name: 'rent', label: '租金', field: 'rent', align: 'left', classes },
    { name: 'area', label: '面积', field: 'area', align: 'left', classes },
    { name: 'tags', label: '标签', field: 'tags', align: 'left', classes },
    { name: 'locationInfo', label: '位置信息', field: 'locationInfo', align: 'left', classes },
    { name: 'images', label: '图片', field: 'images', align: 'left', classes },
    { name: 'arLink', label: 'AR看房链接', field: 'arLink', align: 'left', classes },
    { name: 'description', label: '说明', field: 'description', align: 'left', classes },
    { name: 'action', label: '操作', field: 'action', align: 'left', classes }
  ]
  function request(context: TRequestParam) {
    const { page, rowsPerPage } = context.pagination
    const params: THouseQueryParams = { pageNum: page, pageSize: rowsPerPage }
    if (statusRef.value !== '全部状态') {
      params['status'] = statusRef.value
    }
    if (layoutRef.value !== '全部户型') {
      params['layout'] = layoutRef.value
    }
    if (filterRef.value) {
      params['houseName'] = filterRef.value
    }
    return getHousePageList(params)
  }
  function refreshGridData() {
    if (tableRef.value) {
      tableRef.value.refreshUserTable(1)
    }
  }
  // 新增、编辑功能
  let houseId = -1
  const editStatusOptions = ['未租', '已租']
  const editHouseTypeOptions = ['公寓', '别墅']
  const editLayoutOptions = ['单身公寓', '1室1厅', '2室1厅', '2室2厅', '3室1厅', '3室2厅']
  const editRow: IHouseParam = {
    houseName: '',
    houseType: '公寓',
    status: '未租',
    houseNumber: '',
    layout: '1室1厅',
    rent: 0,
    area: 0,
    tags: '',
    locationInfo: '',
    images: '',
    arLink: '',
    description: ''
  }
  const pEditRow = reactive<IHouseParam>(Object.assign({}, editRow))
  const rUploader = useTemplateRef<QUploader>('q_uploader')
  const rUploaderExcel = useTemplateRef<QUploader>('q_uploader_excel')
  let uploadList: { url: string; signedUrl: string }[] = []
  const rUploadedList = ref<string[]>([])
  const oUser = getUserInfo() as IUser
  const headers = [{ name: 'Authorization', value: `Bearer ${oUser.accessToken}` }]
  function onRemove(row: any) {
    if (row) {
      $q.dialog({
        title: '确认',
        message: '你确定要删除这个条记录吗?',
        cancel: true,
        persistent: true
      }).onOk(() => {
        removeHouse(row.houseId)
          .then(res => {
            if (isRequestSuccess(res)) {
              refreshGridData()
            }
          })
          .catch(error => {
            console.log(error)
          })
      })
    }
  }
  function onKeyInput(event: KeyboardEvent) {
    if (event.key.toLowerCase() === 'enter') {
      // 13 为回车键
      refreshGridData()
    }
  }
  // dialog
  const rShowDialog = ref(false)
  function onRemoveUploadedImg(index: number) {
    rUploadedList.value.splice(index, 1)
  }
  function onShowDialog(row?: any) {
    uploadList = []
    if (row) {
      houseId = row.houseId
    } else {
      houseId = -1
      row = editRow
    }
    const keys = Object.keys(editRow) as (keyof IHouseParam)[]
    keys.forEach(key => {
      pEditRow[key] = row[key]
    })
    rUploadedList.value = row.images ? row.images.split(',') : []
    rShowDialog.value = true
  }
  function onCancel() {
    rShowDialog.value = false
  }
  function getHouseParam() {
    if (pEditRow.rent) {
      pEditRow.rent = +pEditRow.rent
    }
    if (pEditRow.area) {
      pEditRow.area = +pEditRow.area
    }
    const param = { ...pEditRow }
    const imageList: string[] = [...rUploadedList.value]
    uploadList.forEach(item => {
      if (item.url) {
        imageList.push(item.url)
      }
    })
    param.images = imageList.length ? imageList.join() : ''
    return param
  }
  const cDisabled = computed(() => rUploader.value && rUploader.value.isUploading)

  async function onFinish() {
    const oParams = getHouseParam()
    const res = await (houseId === -1
      ? addHouse({ ...oParams })
      : editHouse({ ...oParams, houseId }))
    if (isRequestSuccess(res)) {
      $q.notify({
        type: 'positive',
        message: '提交成功'
      })
      refreshGridData()
    } else {
      $q.notify({
        color: 'red-5',
        textColor: 'white',
        icon: 'warning',
        message: '提交失败'
      })
    }
    onCancel()
  }
  async function onDialogSubmit() {
    const isUpload = rUploader.value && rUploader.value.queuedFiles.length
    if (isUpload) {
      rUploader.value.upload()
    } else {
      await onFinish()
    }
  }
  function addUploadFile(event: Event) {
    if (rUploader.value) {
      rUploader.value.pickFiles(event)
    }
  }
  function onUploaded(info: any) {
    try {
      const res = JSON.parse(info.xhr.response)
      if (res.code == 200 && res.data && res.data.url) {
        uploadList.push(res.data)
      }
    } catch (e) {
      console.log(e, '上传内容解析错误')
    }
  }
  function onUploadedExcel() {
    rUid.value = uid()
    $q.notify({
      type: 'positive',
      message: '已上传成功'
    })
    refreshGridData()
  }
  function onBatchUpload(event: Event) {
    if (rUploaderExcel.value) {
      rUploaderExcel.value.pickFiles(event)
    }
  }

  function onFailed(info: any) {
    const fileNames = info.files.map((file: IOption) => file.name).join(',')
    rUid.value = uid()
    $q.notify({
      color: 'red-5',
      textColor: 'white',
      icon: 'warning',
      message: `${fileNames}上传失败，请重试`
    })
  }
</script>

<template>
  <q-page class="bg-[#FAFCFF] p-5">
    <CudTable
      ref="houseTable"
      class="bg-white p-5"
      title="房源管理"
      row-key="houseId"
      :columns="columns"
      :request="request">
      <template v-slot:body-cell-action="{ row }">
        <td class="text-center w-[120px]">
          <span @click="onShowDialog(row)" class="text-[#2265D4] cursor-pointer">编辑</span>
          <span @click="onRemove(row)" class="text-[#EB4242] cursor-pointer ml-2">删除</span>
        </td>
      </template>
      <template v-slot:top-right>
        <q-select
          class="w-[200px] mr-3"
          outlined
          v-model="statusRef"
          @update:model-value="refreshGridData"
          :options="statusOptions"
          dense
          options-dense></q-select>
        <q-select
          class="w-[200px] mr-3"
          outlined
          v-model="layoutRef"
          @update:model-value="refreshGridData"
          :options="layoutOptions"
          dense
          options-dense></q-select>

        <q-input
          outlined
          dense
          debounce="500"
          v-model="filterRef"
          @blur="refreshGridData"
          @keydown="onKeyInput"
          placeholder="请输入房源名称查询">
          <template v-slot:append>
            <q-icon class="cursor-pointer" name="search" @click="refreshGridData" />
          </template>
        </q-input>
        <a href="https://nick-house-img.oss-cn-shenzhen.aliyuncs.com/房源模板.xlsx">
          <q-btn color="primary" class="ml-4" label="下载模板" />
        </a>
        <q-btn color="primary" class="ml-4" label="批量上传" @click="onBatchUpload" />
        <q-uploader
          :key="rUid"
          class="ud-q-uploader ud-q-uploader-excel"
          auto-upload
          url="http://47.115.213.19/house/house/upload"
          field-name="file"
          :headers="headers"
          @failed="onFailed"
          @uploaded="onUploadedExcel"
          ref="q_uploader_excel" />
        <q-btn color="primary" class="ml-4" @click="onShowDialog()">
          <q-icon left size="1em" name="bi-plus-circle" />
          <div>新增</div>
        </q-btn>
      </template>
    </CudTable>
    <q-dialog v-model="rShowDialog" class="ud-dialog">
      <q-card class="!max-w-none w-[80%] flex flex-col no-wrap">
        <q-card-section class="text-h6 text-[#409EFD] relative">
          <div class="text-h6 text-[#409EFD] relative">
            <b class="v-blue-line"></b>
            房源信息
          </div>
        </q-card-section>

        <q-form @submit="onDialogSubmit" class="flex-1 flex flex-col">
          <div class="flex-1 px-8">
            <q-card-section horizontal>
              <div class="flex-1 flex items-center">
                <div class="w-[143px] text-right text-lg text-[#333]">房源名称：</div>
                <q-input
                  class="flex-1 pb-0"
                  v-model="pEditRow.houseName"
                  outlined
                  dense
                  placeholder="请输入房源名称，建议30字以内"
                  hint=""
                  lazy-rules
                  :rules="[val => !!val || '请输入房源名称，建议30字以内']"></q-input>
              </div>
              <div class="flex-1 flex items-center">
                <div class="w-[143px] text-right text-lg text-[#333]">房源类型：</div>
                <q-select
                  outlined
                  class="flex-1"
                  v-model="pEditRow.houseType"
                  :options="editHouseTypeOptions"
                  dense
                  options-dense></q-select>
              </div>
            </q-card-section>
            <q-card-section horizontal class="mt-5">
              <div class="flex-1 flex items-center">
                <div class="w-[143px] text-right text-lg text-[#333]">状态：</div>
                <q-select
                  outlined
                  class="flex-1"
                  v-model="pEditRow.status"
                  :options="editStatusOptions"
                  dense
                  options-dense></q-select>
              </div>
              <div class="flex-1 flex items-center">
                <div class="w-[143px] text-right text-lg text-[#333]">房号：</div>
                <q-input
                  class="flex-1 pb-0"
                  v-model="pEditRow.houseNumber"
                  outlined
                  dense
                  placeholder="请输入房号"
                  hint=""
                  lazy-rules
                  :rules="[val => !!val || '请输入房号']"></q-input>
              </div>
            </q-card-section>
            <q-card-section horizontal class="mt-5">
              <div class="flex-1 flex items-center">
                <div class="w-[143px] text-right text-lg text-[#333]">户型：</div>
                <q-select
                  outlined
                  class="flex-1"
                  v-model="pEditRow.layout"
                  :options="editLayoutOptions"
                  dense
                  options-dense></q-select>
              </div>
              <div class="flex-1 flex items-center">
                <div class="w-[143px] text-right text-lg text-[#333]">
                  租金
                  <span class="text-sm text-[#666]">(元)</span>
                  ：
                </div>
                <q-input
                  class="flex-1 pb-0"
                  v-model="pEditRow.rent"
                  type="number"
                  outlined
                  dense
                  placeholder="请输入租金"></q-input>
              </div>
            </q-card-section>
            <q-card-section horizontal class="mt-5">
              <div class="flex-1 flex items-center">
                <div class="w-[143px] text-right text-lg text-[#333]">
                  面积
                  <span class="text-sm text-[#666]">(平方米)</span>
                  ：
                </div>
                <q-input
                  class="flex-1 pb-0"
                  v-model="pEditRow.area"
                  type="number"
                  outlined
                  dense
                  placeholder="请输入面积"></q-input>
              </div>
              <div class="flex-1 flex items-center">
                <div class="text-right text-lg text-[#333] w-[143px]">位置信息：</div>
                <q-input
                  class="flex-1 pb-0"
                  v-model="pEditRow.locationInfo"
                  outlined
                  dense></q-input>
              </div>
            </q-card-section>
            <q-card-section horizontal class="mt-5">
              <div class="flex-1 flex items-center">
                <div class="text-right text-lg text-[#333] w-[143px]">标签：</div>
                <q-input
                  class="flex-1 pb-0"
                  v-model="pEditRow.tags"
                  outlined
                  dense
                  placeholder="请输入标签名称，建议3～6个，以中文逗号"></q-input>
              </div>
              <div class="flex-1 flex items-center">
                <div class="text-right text-lg text-[#333] w-[143px]">AR看房链接：</div>
                <q-input
                  class="flex-1 pb-0"
                  v-model="pEditRow.arLink"
                  outlined
                  dense
                  placeholder="请输入AR看房链接"></q-input>
              </div>
            </q-card-section>
            <q-card-section horizontal class="mt-5">
              <div class="flex-1 flex items-center">
                <div class="text-right text-lg text-[#333] w-[143px]">说明：</div>
                <q-input
                  class="flex-1 pb-0"
                  v-model="pEditRow.description"
                  outlined
                  dense
                  placeholder="请输入说明"></q-input>
              </div>
              <div class="flex-1"></div>
            </q-card-section>
            <q-card-section horizontal class="mt-5">
              <div class="flex items-center mr-5">
                <div class="text-right text-lg text-[#333] w-[143px]">上传图片：</div>
                <div class="ud-add-btn" @click="addUploadFile">+</div>
              </div>
              <div class="flex-1 flex items-center gap-5">
                <q-uploader
                  class="ud-q-uploader"
                  :headers="headers"
                  url="http://47.115.213.19/house/upload"
                  field-name="file"
                  @failed="onFailed"
                  @uploaded="onUploaded"
                  @finish="onFinish"
                  ref="q_uploader"
                  multiple
                  accept="image/*" />
                <div class="ud-uploaded-list-box">
                  <div class="ud-uploaded-img-box" v-for="(src, index) in rUploadedList" :key="src">
                    <div class="ud-img-mask">
                      <q-btn
                        round
                        dense
                        flat
                        color="white"
                        icon="clear"
                        @click="onRemoveUploadedImg(index)"></q-btn>
                    </div>
                    <img :src="src" />
                  </div>
                </div>
              </div>
            </q-card-section>
          </div>

          <div class="flex flex-center gap-7 pb-5 mt-5">
            <q-btn
              :disabled="cDisabled"
              color="blue-6"
              padding="10px 40px"
              text-color="white"
              label="确认"
              type="submit" />
            <q-btn outline padding="10px 40px" @click="onCancel" color="light-blue" label="取消" />
          </div>
        </q-form>
      </q-card>
    </q-dialog>
  </q-page>
</template>

<style scoped lang="scss">
  .ud-add-btn {
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    width: 100px;
    height: 100px;
    background: rgba(34, 101, 212, 0.1);
    border-radius: 4px;
    border: 1px solid #2265d4;
    font-family:
      PingFangSC,
      PingFang SC;
    font-weight: 100;
    font-size: 40px;
    color: #2265d4;
    line-height: 56px;
  }
  .ud-uploaded-list-box {
    display: flex;
    gap: 20px;
    align-items: center;
    flex-wrap: wrap;
    .ud-uploaded-img-box {
      position: relative;
      margin: 8px 0 0;
      padding: 0;
      width: 200px;
      height: 150px;
      .ud-img-mask {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 5;
        background-color: rgba(0, 0, 0, 0.5);
        .q-btn {
          position: absolute;
          top: 6px;
          right: 8px;
        }
      }
      img {
        width: 100%;
        height: auto;
        max-height: 100%;
      }
    }
  }
</style>
